﻿using System;
using System.Collections.Generic;
using RenRen.Schema;
using RenRen.Session;
using RenRen.Utility;
using RenRen.Common;

namespace RenRen.Rest
{
    /// <summary>
    /// RenRen用户接口
    /// </summary>
    public class Users : RestBase
    {
        #region Methods

        #region Constructor
        public Users(RenRenSession session)
            : base(session)
        {
        }

        #endregion Constructor

        #region Public Methods
    
 

        #region Synchronous Methods
        
        /// <summary>
        /// 得到用户信息，当对方设置了隐私权限，只能返回用户的姓名（name）、性别（sex）、是否为星级用户（star）、头像（headurl）等数据
        /// </summary>
        /// <returns>用户对象</returns>
        public user GetInfo()
        {
            return GetInfo(Session.UserId);
        }

        /// <summary>
        /// 得到用户信息，当对方设置了隐私权限，只能返回用户的姓名（name）、性别（sex）、是否为星级用户（star）、头像（headurl）等数据
        /// </summary>
        /// <param name="uid">用户ID</param>
        /// <returns>用户对象</returns>
        public user GetInfo(int uid)
        {
            var users = GetInfo(uid.ToString());
            return users.Count > 0 ? users[0] : null;
        }

        /// <summary>
        /// 得到用户信息，当对方设置了隐私权限，只能返回用户的姓名（name）、性别（sex）、是否为星级用户（star）、头像（headurl）等数据
        /// </summary>
        /// <param name="uids">一组用户IDs</param>
        /// <returns>用户对象</returns>
        public IList<user> GetInfo(List<int> uids)
        {
            return GetInfo(uids.AsString());
        }

        /// <summary>
        /// 得到当前session的用户ID，返回的ID值应该在session有效期内被存储，从而避免重复地调用该方法。
        /// </summary>
        /// <returns>当前session的用户ID</returns>
        public int GetLoggedInUser()
        {
            return GetLoggedInUser(false, null, null);
        }


        /// <summary>
        /// 判断用户是否已经对应用授权
        /// </summary>
        /// <param name="uid">用户</param>
        public bool IsAppUser(int uid)
        {
            return IsAppUser(uid, false, null, null);
        }    
        #endregion Synchronous Methods

 

        #region Asynchronous Methods

        /// <summary>
        /// 异步得到用户信息，
        /// 当对方设置了隐私权限，只能返回用户的姓名（name）、性别（sex）、是否为星级用户（star）、头像（headurl）等数据
        /// </summary>
        /// <param name="callback">异步回调代理</param>
        /// <param name="state">异步调用状态对象</param>      
        /// <returns>用户</returns>
        public void GetInfoAsync(GetInfoCallback callback, Object state)
        {
            GetInfoAsync(Session.UserId, callback, state);
        }

        /// <summary>
        /// 异步得到用户信息，
        /// 当对方设置了隐私权限，只能返回用户的姓名（name）、性别（sex）、是否为星级用户（star）、头像（headurl）等数据
        /// </summary>
        /// <param name="callback">异步回调代理</param>
        /// <param name="state">异步调用状态对象</param>      
        /// <returns>用户</returns>
        public void GetInfoAsync(int uid, GetInfoCallback callback, Object state)
		{
			GetInfoAsync(uid.ToString(), callback, state);
		}

        /// <summary>
        /// 异步得到用户信息，
        /// 当对方设置了隐私权限，只能返回用户的姓名（name）、性别（sex）、是否为星级用户（star）、头像（headurl）等数据
        /// </summary>
        /// <param name="callback">异步回调代理</param>
        /// <param name="state">异步调用状态对象</param>      
        /// <returns>用户</returns>
        public void GetInfoAsync(List<int> uids, GetInfoCallback callback, Object state)
        {
            GetInfo(uids.AsString(), true, callback, state);
        }

        /// <summary>
        /// 异步得到用户信息，
        /// 当对方设置了隐私权限，只能返回用户的姓名（name）、性别（sex）、是否为星级用户（star）、头像（headurl）等数据
        /// </summary>
        /// <param name="callback">异步回调代理</param>
        /// <param name="state">异步调用状态对象</param>      
        /// <returns>用户</returns>
        public void GetInfoAsync(string uids, GetInfoCallback callback, Object state)
		{
			GetInfo(uids, true, callback, state);
		}

        ///  <summary>
        ///  得到当前session的用户ID，返回的ID值应该在session有效期内被存储，从而避免重复地调用该方法。
        ///  </summary>
        /// <param name="callback">异步回调代理</param>
        /// <param name="state">异步调用状态对象</param>       
        /// <returns>用户</returns>
        public void GetLoggedInUserAsync(GetLoggedInUserCallback callback, Object state)
        {
            GetLoggedInUser(true, callback, state);
        }

        /// <summary>
        /// 判断用户是否已经对应用授权
        /// </summary>
        /// <param name="uid">用户</param>
        public void IsAppUserAsync(int uid, IsAppUserCallback callback, Object state)
        {
            IsAppUser(uid, true, callback, state);
        }
 


        #endregion Asynchronous Methods

        #endregion Public Methods

        #region Internal Methods

        /// <summary>
        /// 得到用户信息
        /// </summary>
        internal IList<user> GetInfo(string uids)
        {
            return GetInfo(uids, false, null, null);
        }

        #endregion Internal Methods
        
        #region Private Methods
        
        private IList<user> GetInfo(string uids, bool isAsync, GetInfoCallback callback, Object state)
        {
            var parameterList = new Dictionary<string, string> { { "method", "xiaonei.users.getInfo" } };
            Utilities.AddOptionalParameter(parameterList, "uids", uids);
            if (string.IsNullOrEmpty(Session.SessionKey))
            {
                Utilities.AddRequiredParameter(parameterList, "fields",
                                  "uid,name");
            }
            else
            {
                Utilities.AddRequiredParameter(parameterList, "fields",
                                  "uid,name,sex,star,zidou,birthday,tinyurl,headurl,mainurl,hometown_location,work_history,university_history,hs_history,contact_info,books,movies,music");
            }
            
            if (isAsync)
            {
                SendRequestAsync<users_getInfo_response, IList<user>>(parameterList,HasSession, new RenRenCallCompleted<IList<user>>(callback), state, "user");
                return null;
            }

			var response = SendRequest<users_getInfo_response>(parameterList,HasSession);
			return response == null ? null : response.user;
        }

        

        private int GetLoggedInUser(bool isAsync, GetLoggedInUserCallback callback, Object state)
        {
            var parameterList = new Dictionary<string, string> { { "method", "xiaonei.users.getLoggedInUser" } };

            if (isAsync)
            {
                SendRequestAsync<users_getLoggedInUser_response, int>(parameterList, new RenRenCallCompleted<int>(callback), state); 
               return 0;
            }

			var response = SendRequest<users_getLoggedInUser_response>(parameterList);
			return response == null ? 0 : int.Parse(response.Value) ;
        }

        private bool IsAppUser(int uid, bool isAsync, IsAppUserCallback callback, Object state)
        {
            var parameterList = new Dictionary<string, string> { { "method", "xiaonei.users.isAppUser" } };
            Utilities.AddOptionalParameter(parameterList, "uid", uid);

            if (isAsync)
            {
                SendRequestAsync<string, bool>(parameterList,HasSession, new RenRenCallCompleted<bool>(callback), state);
                return false;
            }

            var response = SendRequest<string>(parameterList,HasSession);
			return response == null ? true : false ;
        }

        #endregion Private Methods
        
        #endregion Methods

        #region Delegates
        public delegate void GetInfoCallback(IList<user> users, Object state, RenRenException e);
        public delegate void GetLoggedInUserCallback(int userId, Object state, RenRenException e);
        public delegate void GetStandardInfoCallback(IList<user> users, Object state, RenRenException e);
        public delegate void HasAppPermissionCallback(bool hasPermission, Object state, RenRenException e);
        public delegate void IsAppUserCallback(bool isAppUser, Object state, RenRenException e);
		public delegate void IsVerifiedCallback(bool isVerified, Object state, RenRenException e);
		public delegate void SetStatusCallback(bool result, Object state, RenRenException e);

        #endregion Delegates
    }
}
